package com.cloud.easy.im.argeement;

import com.alibaba.fastjson.JSON;
import com.cloud.easy.im.utils.CharsetHelper;
import com.cloud.easy.im.utils.SequenceIdUtil2;

import java.io.Serializable;

/**
 * 协议内容实体
 *
 * @author wangjian
 * @version 0.1.0
 * @create 2020年09月02日5:13 下午
 */
public class Agreement implements Serializable {

    private static final long serialVersionUID = -2595525523307115662L;
    /**
     * 意义：协议类型。
     **/
    private byte type = 0;
    /**
     * 意义：协议数据内容。
     **/
    private String dataContent = null;

    /**
     * 意义：消息发出方的id 说明：为“-1”表示未设定、`为“0”表示来自Server。
     **/
    private String from = "-1";
    /**
     * 意义：消息接收方的id（当用户退出时，此值可不设置） 说明：为“-1”表示未设定、为“0”表示发给Server。
     **/
    private String to = "-1";

    /**
     * 意义：用于QoS消息包的质量保证时作为消息的指纹FingerPrint特征码（理论上全局唯一）。
     **/
    private String fp = null;

    /**
     * 意义：代表此次消息是否需要Qos支持，通过ack方式保证通讯的完整性
     */
    private boolean QoS = false;

    /**
     * 本字段仅用于客户端QoS时：表示丢包重试次数
     **/
    private transient int retryCount = 0;

    /**
     * [重要]意义: 应用层专用字段——用于应用层存放推送(推)、广播(拉)等场景下的消息类型。
     */
    private byte utype = 0;

    /**
     * 意义：服务端收到时间戳，所有消息已服务端收到为准
     */
    private long times = 0;

    /**
     * 产品Code
     */
    private Integer productCode = null;

    /**
     * 服务端标示
     */
    public static String serverMark = "0";


    public Agreement(byte type, String dataContent, String from, String to, Integer productCode) {
        this(type, dataContent, from, to, false, null, (byte) -1, productCode);
    }

    public Agreement(byte type, String dataContent, String from, String to
            , boolean QoS, String fingerPrint, byte utype, Integer productCode) {
        this.type = type;
        this.dataContent = dataContent;
        this.from = from;
        this.to = to;
        this.QoS = QoS;
        this.utype = utype;
        this.productCode = productCode;

        if (fingerPrint == null) {
            fp = genFingerPrint();
        } else {
            fp = fingerPrint;
        }
    }

    public Integer getProductCode() {
        return productCode;
    }

    public void setProductCode(Integer productCode) {
        this.productCode = productCode;
    }

    public byte getType() {
        return type;
    }

    public void setType(byte type) {
        this.type = type;
    }

    public String getDataContent() {
        return dataContent;
    }

    public void setDataContent(String dataContent) {
        this.dataContent = dataContent;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String toJsonString() {
        return JSON.toJSONString(this);
    }

    public byte[] toBytes() {
        return CharsetHelper.getBytes(toJsonString());
    }

    public boolean isQoS() {
        return QoS;
    }

    public void setQoS(boolean qoS) {
        QoS = qoS;
    }

    public int getRetryCount() {
        return retryCount;
    }

    public void setRetryCount(int retryCount) {
        this.retryCount = retryCount;
    }

    public void increaseRetryCount() {
        this.retryCount += 1;
    }

    public String getFp() {
        return fp;
    }

    public void setFp(String fp) {
        this.fp = fp;
    }

    public byte getUtype() {
        return utype;
    }

    public void setUtype(byte utype) {
        this.utype = utype;
    }

    public long getTimes() {
        return times;
    }

    public void setTimes(long times) {
        this.times = times;
    }

    public String genFingerPrint() {
        return SequenceIdUtil2.getMsgId().toString();
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Agreement clone = new Agreement(this.getType()
                , this.getDataContent(), this.getFrom(), this.getTo(), this.isQoS(), this.getFp(), this.getUtype(),this.getProductCode());
        return clone;
    }
}
